﻿using CastingWellEquipmentGUI.Config;
using CastingWellEquipmentGUI.Utils;
using CastingWellEquipmentGUI.View;
using CastingWellEquipmentGUI.View.Modal.CalendarWindow;
using CastingWellEquipmentGUI.View.Modal.CastWellPublic;
using CastingWellEquipmentGUI.View.Modal.CastWellPublicAuxiliary;
using CastingWellEquipmentGUI.View.Modal.DeleteWindow;
using CastingWellEquipmentGUI.View.Modal.EditCastingNoPanel;
using CastingWellEquipmentGUI.View.Modal.ExitApplication;
using CastingWellEquipmentGUI.View.Modal.Launde;
using CastingWellEquipmentGUI.View.Modal.RecipeSelection;
using CastingWellEquipmentGUI.View.Modal.SwitchSystem;
using CastingWellEquipmentGUI.View.Modal.WireFeeder;
using CastingWellEquipmentGUI.ViewModel.Common.WindowsManager;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using WinInterop = System.Windows.Interop;
using System.Runtime.InteropServices;
using CastingWellEquipmentGUI.View.Pages;
using CastingWellEquipmentGUI.View.Modal.SettingMenuPages;
using CastingWellEquipmentGUI.View.Modal.HydraulicSystem;
using CastingWellEquipmentGUI.View.Modal;
using CastingWellEquipmentGUI.View.Modal.WaterSupplySystem;
using CastingWellEquipmentGUI.View.Modal.DrainageSystem;

namespace CastingWellEquipmentGUI
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class Login : Window
    {
        private Storyboard sb = new Storyboard();//首先实例化一个故事板
        public Login()
        {
            InitializeComponent();
            this.SourceInitialized += new EventHandler(win_SourceInitialized);
            #region 只能运行一个客户端程序
            System.Diagnostics.Process[] myProcesses = System.Diagnostics.Process.GetProcessesByName("CastingWellEquipmentGUI");//获取指定的进程名  
            if (myProcesses.Length > 1) //如果可以获取到知道的进程名则说明已经启动
            {
                MessageBox.Show("只能运行一个本程序！", "警告", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                Environment.Exit(1);//退出程序
            }
            #endregion 只能运行一个客户端程序
            //调用窗体注册
            WindowsRegister();
            //加载或创建应用配置
            LoadOrCreateApplicationConfiginfo();

            //隐藏本窗体
            Messenger.Default.Register<NotificationMessage>(this, (nm) =>
            {
                if (nm.Notification == "HideLogin")
                {
                    if (nm.Sender == DataContext)
                    {
                        Hide();
                    }
                }
            });
            //权限分析
            Messenger.Default.Register<NotificationMessage>(this, (nm) =>
            {
                if (nm.Notification == "Analysis form control structure generation permission")
                {
                    if (nm.Sender == DataContext)
                    {
                        AnalysisFormControlStructureGenerationPermission();
                    }
                }
            });
            string path = Environment.CurrentDirectory + "\\images\\Login\\login.gif";
            GifMedia.Source = new Uri(path, UriKind.Absolute);
            GifMedia.Play();

            //去执行登录动画
            Messenger.Default.Register<NotificationMessage>(this, (nm) =>
            {
                if (nm.Notification == "DoLogin")
                {
                    if (nm.Sender == DataContext)
                    {
                        #region 生成权限数据

                        GifMediaLogin.Source = new Uri(Environment.CurrentDirectory + "\\images\\Login\\loginLoad.gif", UriKind.Absolute);
                        GifMediaLogin.Position = TimeSpan.FromMilliseconds(1);
                        GifMediaLogin.Play();

                        #endregion 生成权限数据
                    }
                }
            });
            //注册动画剧本完成时间
            sb.Completed += Sb_Completed;


        }
        #region 最大化显示任务栏

        void win_SourceInitialized(object sender, EventArgs e)
        {
            System.IntPtr handle = (new WinInterop.WindowInteropHelper(this)).Handle;
            WinInterop.HwndSource.FromHwnd(handle).AddHook(new WinInterop.HwndSourceHook(WindowProc));
        }

        private static System.IntPtr WindowProc(
              System.IntPtr hwnd,
              int msg,
              System.IntPtr wParam,
              System.IntPtr lParam,
              ref bool handled)
        {
            switch (msg)
            {
                case 0x0024:
                    WmGetMinMaxInfo(hwnd, lParam);
                    handled = true;
                    break;
            }

            return (System.IntPtr)0;
        }

        private static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam)
        {

            MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));

            // Adjust the maximized size and position to fit the work area of the correct monitor
            int MONITOR_DEFAULTTONEAREST = 0x00000002;
            System.IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

            if (monitor != System.IntPtr.Zero)
            {

                MONITORINFO monitorInfo = new MONITORINFO();
                GetMonitorInfo(monitor, monitorInfo);
                RECT rcWorkArea = monitorInfo.rcWork;
                RECT rcMonitorArea = monitorInfo.rcMonitor;
                mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
                mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);
                mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
                mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
            }

            Marshal.StructureToPtr(mmi, lParam, true);
        }


        /// <summary>
        /// POINT aka POINTAPI
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            /// <summary>
            /// x coordinate of point.
            /// </summary>
            public int x;
            /// <summary>
            /// y coordinate of point.
            /// </summary>
            public int y;

            /// <summary>
            /// Construct a point of coordinates (x,y).
            /// </summary>
            public POINT(int x, int y)
            {
                this.x = x;
                this.y = y;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MINMAXINFO
        {
            public POINT ptReserved;
            public POINT ptMaxSize;
            public POINT ptMaxPosition;
            public POINT ptMinTrackSize;
            public POINT ptMaxTrackSize;
        };



        /// <summary>
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class MONITORINFO
        {
            /// <summary>
            /// </summary>            
            public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));

            /// <summary>
            /// </summary>            
            public RECT rcMonitor = new RECT();

            /// <summary>
            /// </summary>            
            public RECT rcWork = new RECT();

            /// <summary>
            /// </summary>            
            public int dwFlags = 0;
        }


        /// <summary> Win32 </summary>
        [StructLayout(LayoutKind.Sequential, Pack = 0)]
        public struct RECT
        {
            /// <summary> Win32 </summary>
            public int left;
            /// <summary> Win32 </summary>
            public int top;
            /// <summary> Win32 </summary>
            public int right;
            /// <summary> Win32 </summary>
            public int bottom;

            /// <summary> Win32 </summary>
            public static readonly RECT Empty = new RECT();

            /// <summary> Win32 </summary>
            public int Width
            {
                get { return Math.Abs(right - left); }  // Abs needed for BIDI OS
            }
            /// <summary> Win32 </summary>
            public int Height
            {
                get { return bottom - top; }
            }

            /// <summary> Win32 </summary>
            public RECT(int left, int top, int right, int bottom)
            {
                this.left = left;
                this.top = top;
                this.right = right;
                this.bottom = bottom;
            }


            /// <summary> Win32 </summary>
            public RECT(RECT rcSrc)
            {
                this.left = rcSrc.left;
                this.top = rcSrc.top;
                this.right = rcSrc.right;
                this.bottom = rcSrc.bottom;
            }

            /// <summary> Win32 </summary>
            public bool IsEmpty
            {
                get
                {
                    // BUGBUG : On Bidi OS (hebrew arabic) left > right
                    return left >= right || top >= bottom;
                }
            }
            /// <summary> Return a user friendly representation of this struct </summary>
            public override string ToString()
            {
                if (this == RECT.Empty) { return "RECT {Empty}"; }
                return "RECT { left : " + left + " / top : " + top + " / right : " + right + " / bottom : " + bottom + " }";
            }

            /// <summary> Determine if 2 RECT are equal (deep compare) </summary>
            public override bool Equals(object obj)
            {
                if (!(obj is Rect)) { return false; }
                return (this == (RECT)obj);
            }

            /// <summary>Return the HashCode for this struct (not garanteed to be unique)</summary>
            public override int GetHashCode()
            {
                return left.GetHashCode() + top.GetHashCode() + right.GetHashCode() + bottom.GetHashCode();
            }


            /// <summary> Determine if 2 RECT are equal (deep compare)</summary>
            public static bool operator ==(RECT rect1, RECT rect2)
            {
                return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && rect1.bottom == rect2.bottom);
            }

            /// <summary> Determine if 2 RECT are different(deep compare)</summary>
            public static bool operator !=(RECT rect1, RECT rect2)
            {
                return !(rect1 == rect2);
            }


        }

        [DllImport("user32")]
        internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);

        /// <summary>
        /// 
        /// </summary>
        [DllImport("User32")]
        internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);

        #endregion
        /// <summary>
        /// 播放完成登录动画执行登录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Sb_Completed(object sender, EventArgs e)
        {
            Messenger.Default.Send<string>(null, "GoLogin");
        }



        /// <summary>
        /// 加载或创建应用配置
        /// </summary>
        private void LoadOrCreateApplicationConfiginfo()
        {

            //创建配置文件，并初始化对应的配置参数
            string xmlFilePath = SystemConfig.xmlFilePath;
            if (!File.Exists(xmlFilePath))
            {
                XmlHelper applicationConfig = new XmlHelper();
                applicationConfig.CreateXmlDocument("ApplicationConfig.xml", "ApplicationConfig", "utf-8");
                //数据库IP地址
                applicationConfig.InsertNode(xmlFilePath,
                                             "DataBaseIpAddress",
                                             true,
                                             "ApplicationConfig",
                                             new Hashtable
                                             {
                                                { "value", "127.0.0.1" }
                                             },
                                             null);
                //设备类别
                applicationConfig.InsertNode(xmlFilePath,
                                             "EquipmentCategory",
                                             true,
                                             "ApplicationConfig",
                                             new Hashtable
                                             {
                                                { "value", "扁锭" }
                                             },
                                             null);
            }
            else
            {
                XmlHelper applicationConfig = new XmlHelper();
                //加载数据库IP地址至全局配置变量
                XmlNode dataBaseIpAddressXmlNode = applicationConfig.GetXmlNodeByXpath(xmlFilePath, "//ApplicationConfig//DataBaseIpAddress");
                SystemConfig.dataBaseIpAddress = dataBaseIpAddressXmlNode.Attributes["value"].Value;
                //加载设备类别至全局配置变量
                XmlNode equipmentCategoryXmlNode = applicationConfig.GetXmlNodeByXpath(xmlFilePath, "//ApplicationConfig//EquipmentCategory");
                SystemConfig.equipmentCategory = equipmentCategoryXmlNode.Attributes["value"].Value;
            }
        }

        /// <summary>
        /// 窗体注册
        /// 注册到窗体管理器和数据库中
        /// 存在数据库中是为权限控制
        /// </summary>
        private void WindowsRegister()
        {


            #region 窗体注册中心 不注册无法打开和隐藏窗体
            //登录窗体
            WindowManager.Register<Login>("Login");
            //系统设置
            WindowManager.Register<SystemSetting>("SystemSetting");
            //主窗体
            WindowManager.Register<Main>("Main");
            //流槽界面模态窗体流槽挡板操作面板
            WindowManager.Register<LaunderBafflePanelWindow>("LaunderBafflePanel");
            //流槽界面模态窗体激光液位仪操作面板
            WindowManager.Register<AuroraLevelGaugePanelWindow>("AuroraLevelGaugePanel");
            //铸井公辅界面模态窗体设置CV值的面板
            WindowManager.Register<SetCVPanelWindow>("SetCVPanel");
            //启动关闭窗体界面
            WindowManager.Register<OnOrOffPanelWindow>("OnOrOffPanel");
            //测试启动关闭窗体界面
            WindowManager.Register<TestOrOnOrOffPanelWindow>("TestOrOnOrOffPanel");
            //自动手动窗体界面
            WindowManager.Register<HandAutoPanelWindow>("HandOrAutoPanel");
            //退出系统
            WindowManager.Register<ExitPanelWindow>("ExitPanel");
            //日期选择窗体
            WindowManager.Register<CalendarWindow>("CalendarWindow");
            //小时选择窗体
            WindowManager.Register<HourWindow>("HourWindow");
            //分钟选择窗体
            WindowManager.Register<MinuteWindow>("MinuteWindow");
            //秒钟选择窗体
            WindowManager.Register<SecondWindow>("SecondWindow");
            //删除配方窗体
            WindowManager.Register<DeleteRecipeWindow>("DeleteRecipeWindow");
            //页码选择窗体
            WindowManager.Register<AllPageNumberPanelWindow>("AllPageNumberPanel");
            //页码选择窗体
            WindowManager.Register<AllPageNumberPanelForCastingRecordWindow>("AllPageNumberPanelForCastingRecordWindow");
            //页码选择窗体
            WindowManager.Register<AllPageNumberPanelForRecipeManageWindow>("AllPageNumberPanelForRecipeManageWindow");
            //状态切换窗体
            WindowManager.Register<SwitchSystemPanelWindow>("SwitchSystemPanelWindow");
            //铸造编号输入窗体
            WindowManager.Register<EditCastingNoPanelWindow>("EditCastingNoPanelWindow");
            //送丝机页面设动手动自动窗体
            WindowManager.Register<WireFeederPageSettingPanel1Window>("WireFeederPageSettingPanel1Window");
            //送丝机页面设动手动正转/反转窗体
            WindowManager.Register<WireFeederPageSetting1Panel1Window>("WireFeederPageSetting1Panel1Window");
            //送丝机页面设SP值窗体
            WindowManager.Register<WireFeederPageSetting2Panel1Window>("WireFeederPageSetting2Panel1Window");
            //控件标签绑定编辑窗体
            WindowManager.Register<ControlTagEditWindow>("ControlTagEditWindow");
            //配方设置编辑窗体
            WindowManager.Register<RecipeTagEditWindow>("RecipeTagEditWindow");
            //液压系统质量流量计设置
            WindowManager.Register<FlowmeterSetPanel>("FlowmeterSetPanel");
            //液压系统质量流量计设置Two
            WindowManager.Register<FlowmeterSetPanelTwo>("FlowmeterSetPanelTow");
            //启动关闭及主辅电机控制窗体界面
            WindowManager.Register<OnOrOffAndZhuOrFuPanelWindow>("OnOrOffAndZhuOrFuPanel");
            //检查清单窗体
            WindowManager.Register<CheckOrderWindow>("CheckOrderWindow");
            #endregion 窗体注册中心 不注册无法打开和隐藏窗体

        }

        private bool AnalysisFormControlStructureGenerationPermission()
        {
            bool result = false;
            //List<Page> pages = new List<Page>
            //{
            //    new WireFeederPage()
            //};
            //for (int i = 0; i < pages.Count; i++)
            //{
            //    FrameworkElement frame = pages[i].L;
            //    List<Control> childControls = new List<Control>();
            //    FindVisualChild(frame, ref childControls);
            //    for (int j = 0; j < childControls.Count; j++)
            //    {

            //    }
            //}
            result = true;
            return result;
            //List<Window> windows = new List<Window>();
        }

        /// <summary>
        /// 最小化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_Min_Click(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }
        /// <summary>
        /// 最大化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_Max_Click(object sender, RoutedEventArgs e)
        {
            if (WindowState == WindowState.Normal)
            {
                WindowState = WindowState.Maximized;
            }
            else
            {
                WindowState = WindowState.Normal;
            }
        }

        private void GifMedia_MediaEnded(object sender, RoutedEventArgs e)
        {
            GifMedia.Position = TimeSpan.FromMilliseconds(1);
            GifMedia.Play();
        }

        private void GifMediaLogin_MediaEnded(object sender, RoutedEventArgs e)
        {
            GifMediaLogin.Visibility = Visibility.Hidden;
            //for (int i = 0; i < Border_Left.Width; i++)
            //{
            //    Thickness thickness = new Thickness(0 - i, 0, 0, 0);
            //    Border_Left.Margin = thickness;
            //    Thread.Sleep(10);
            //}
            //for (int i = 0; i < Border_Right.Width; i++)
            //{
            //    Thickness thickness = new Thickness(Border_Right.Margin.Left + i, 0, 0, 0);
            //    Border_Right.Margin = thickness;
            //    Thread.Sleep(10);
            //}

            DoubleAnimation Border_LeftDa = new DoubleAnimation(0, 0 - Border_Left.Width, new Duration(TimeSpan.FromSeconds(1)));//浮点动画定义了开始值和起始值
            Border_Left.RenderTransform = new TranslateTransform();//在二维x-y坐标系统内平移(移动)对象
            Border_LeftDa.RepeatBehavior = new RepeatBehavior(1);//设置循环播放
            Border_LeftDa.AutoReverse = false;//设置可以进行反转
            Storyboard.SetTarget(Border_LeftDa, Border_Left);//绑定动画为这个按钮执行的浮点动画
            Storyboard.SetTargetProperty(Border_LeftDa, new PropertyPath("RenderTransform.X"));//依赖的属性
            sb.Children.Add(Border_LeftDa);//向故事板中加入此浮点动画
            DoubleAnimation Border_RightDa = new DoubleAnimation(0, this.Width, new Duration(TimeSpan.FromSeconds(1)));//浮点动画定义了开始值和起始值
            Border_Right.RenderTransform = new TranslateTransform();//在二维x-y坐标系统内平移(移动)对象
            Border_RightDa.RepeatBehavior = new RepeatBehavior(1);//设置循环播放
            Border_RightDa.AutoReverse = false;//设置可以进行反转
            Storyboard.SetTarget(Border_RightDa, Border_Right);//绑定动画为这个按钮执行的浮点动画
            Storyboard.SetTargetProperty(Border_RightDa, new PropertyPath("RenderTransform.X"));//依赖的属性
            sb.Children.Add(Border_RightDa);//向故事板中加入此浮点动画
            sb.Begin();//播放此动画
        }


        private void Border_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DragMove();
        }

        private void LoginW_Loaded(object sender, RoutedEventArgs e)
        {
            double WorkAreaWidth = Width;
            double WorkAreaHeight = Height;
            MainGrid.Width = WorkAreaWidth;
            MainGrid.Height = WorkAreaHeight;
            Grid_Left.Width = MainGrid.Width;
            Grid_Left.Height = MainGrid.Height;
            Grid_Right.Width = MainGrid.Width;
            Grid_Right.Height = MainGrid.Height;
            Border_Left.Width = Grid_Left.ColumnDefinitions[0].ActualWidth;
            Border_Left.Height = Grid_Left.Height;
            Border_Right.Width = Grid_Right.ColumnDefinitions[1].ActualWidth;
            Border_Right.Height = Grid_Right.Height;
            GridLoginMain.Width = WorkAreaWidth;
            GridLoginMain.Height = WorkAreaHeight;
            RowDefinitionCollection rowDefinitions = GridLoginMain.RowDefinitions;
            Border_Login.Width = GridLoginMain.ColumnDefinitions[1].ActualWidth;
            double height = Border_Login.Width * 1.282548476454294;
            double shengyu = WorkAreaHeight - height;
            double upsize = shengyu * 0.5581395348837209;
            double lowsize = shengyu - upsize;
            GridLoginMain.RowDefinitions[0].Height = new GridLength(upsize);
            GridLoginMain.RowDefinitions[1].Height = new GridLength(height);
            GridLoginMain.RowDefinitions[2].Height = new GridLength(lowsize);
            //Border_Login.Height = GridLoginMain.RowDefinitions[1].ActualHeight;
            Border_Grid_Login.Width = Border_Login.Width;
            Border_Grid_Login.Height = Border_Login.Height;
            TextBox_Account.Width = Border_Grid_Login.ColumnDefinitions[1].ActualWidth;
            TextBox_Account.Height = Border_Grid_Login.RowDefinitions[1].ActualHeight;
            TextBox_Password.Width = Border_Grid_Login.ColumnDefinitions[1].ActualWidth;
            TextBox_Password.Height = Border_Grid_Login.RowDefinitions[3].ActualHeight;
        }
    }
}
